Ext.define("EC.common.tinymce.WindowManager", {
	extend: tinymce.WindowManager,

	constructor: function(cfg) {
		tinymce.WindowManager.call(this, cfg.editor);
	},
	
	alert: function(txt, cb, s) {
		Ext.MessageBox.alert("", txt, function() {
			if (!Ext.isEmpty(cb)) {
				cb.call(this);
			}
		}, s);
	},
	
	confirm: function(txt, cb, s) {
		Ext.MessageBox.confirm("", txt, function(btn) {
			if (!Ext.isEmpty(cb)) {
				cb.call(this, btn == "yes");
			}
		}, s);
	},
	
	open: function(s, p) {
		s = s || {};
		p = p || {};

		if(!s.type) {
			this.bookmark = this.editor.selection.getBookmark('simple');
		}

		s.width = parseInt(s.width || 320);
		s.height = parseInt(s.height || 240) + (tinymce.isIE ? 8 : 0);
		s.min_width = parseInt(s.min_width || 150);
		s.min_height = parseInt(s.min_height || 100);
		s.max_width = parseInt(s.max_width || 2000);
		s.max_height = parseInt(s.max_height || 2000);
		s.movable = true;
		s.resizable = true;
		p.mce_width = s.width;
		p.mce_height = s.height;
		p.mce_inline = true;

		this.features = s;
		this.params = p;

		var win = Ext.create("Ext.window.Window", {
			title: s.name,
			width: s.width,
			height: s.height,
			minWidth: s.min_width,
			minHeight: s.min_height,
			resizable: true,
			maximizable: s.maximizable,
			minimizable: s.minimizable,
			modal: true,
			stateful: false,
			constrain: true,
			layout: "fit",
			items: [
				Ext.create("Ext.Component", {
					autoEl: {
						tag: 'iframe',
						src: s.url || s.file
					},
					style : 'border-width: 0px;'
				})
			]
		});

		p.mce_window_id = win.getId();

		win.show(null, function() {
			if (s.left && s.top)
				win.setPagePosition(s.left, s.top);
			var pos = win.getPosition();
			s.left = pos[0];
			s.top = pos[1];
			this.onOpen.dispatch(this, s, p);
		}, this);

		return win;
	},
	
	close: function(win) {
		// Probably not inline
		if (!win.tinyMCEPopup || !win.tinyMCEPopup.id) {
			tinymce.WindowManager.prototype.close.call(this, win);
			return;
		}

		var w = Ext.getCmp(win.tinyMCEPopup.id);
		if (w) {
			this.onClose.dispatch(this);
			w.close();
		}
	},
	
	setTitle: function(win, ti) {
		if (!win.tinyMCEPopup || !win.tinyMCEPopup.id) {
			tinymce.WindowManager.prototype.setTitle.call(this, win, ti);
			return;
		}

		var w = Ext.getCmp(win.tinyMCEPopup.id);
		if (w) w.setTitle(ti);
	},
	
	resizeBy: function(dw, dh, id) {
		var w = Ext.getCmp(id);
		if (w) {
			var size = w.getSize();
			w.setSize(size.width + dw, size.height + dh);
		}
	},
	
	focus: function(id) {
		var w = Ext.getCmp(id);
		if (w) w.setActive(true);
	}
	
});


Ext.define("EC.common.tinymce.Editor", {
	extend:'Ext.Component',
	
	mixins: {
		labelable: 'Ext.form.Labelable',
		//field: 'Ext.form.field.Field'
	},
	
	alias: 'widget.TinyMCEEditor',
	alternateClassName: 'Ext.form.TinyMCEEditor',
	
	statics: {
		tinyMCEInitialized: false,
		
		//settings for each TinyMCE instance, override before instantiating any TinyMCE editor to change there.
		globalSettings: {
		//	accessibility_focus: false,
		//	height: 400,
		//	language: "en",
			mode: "none"
		//	skin : "o2k7",
		//	theme: "advanced",
		//	theme_advanced_resizing: false,
			//width: 600
		},
		
		setGlobalSettings: function(settings) {
			Ext.apply(this.globalSettings, settings);
		}
	},
	
	config: {
		tinyMCESettings: {}
	},


	constructor: function(config) {
		//override default tinyMCESettings
		config.tinyMCESettings = Ext.Object.merge(this.statics().globalSettings, config.tinyMCESettings);
		Ext.apply(config, {
			autoEl: {
				tag: "textarea",
				style: "width: 1px; height: 1px;",
				autocomplete: "off"
			}
		});
		this.initConfig(config);

		// Add events
		this.addEvents({
			"editorcreated": true
		});
		
		this.callParent([config]);
		
		return this;
	},
	
	initComponent: function() {
		this.initLabelable();
    	this.initField();
	},
	
	initEvents: function() {
		this.originalValue = this.getValue();
	},
	
	getResizeEl: function() {
		return this.wrapEl;
	},
	
	getName: function() {
		return this.rendered && this.textareaEl.dom.name != undefined ? this.textareaEl.dom.name : (this.name || '');
	},
	
	initValue: function() {
		return a = this;
		if (!this.rendered)
			this.mixins.field.initValue.call(this);
		else {
			if (this.value !== undefined) {
				this.setValue(this.value);
			}
			else {
				var v = this.textareaEl.value; 
				if ( v )
					this.setValue( v );
			}
		}
	},
	
	beforeDestroy: function() {
		if(this.editor) {
			tinyMCE.remove(this.editor);
		}
		if(this.wrapEl) {
			Ext.destroy(this.wrapEl);
		}
		this.callParent();
	},
	
	getRawValue : function() {
		if(!this.rendered || !this.editor.initialized) {
			return Ext.valueFrom(this.value, '');
		}
		return this.editor.getContent();
	},
	
	getValue: function() {
		return this.getRawValue();
	},
	
	setRawValue: function(v) {
		this.value = v;
		if (this.rendered)
			this.withEd(function() {
				this.editor.undoManager.clear();
				this.editor.setContent(v === null || v === undefined ? '' : v);
				this.editor.startContent = this.editor.getContent({ format: 'raw' });
			});
	},

	/** ----------------------------------------------------------
	*/
	setValue: function(v) {
		this.value = v;
		var handle = this;
		if (this.rendered)
			this.withEd(function() {
				this.editor.undoManager.clear();
				this.editor.setContent(v === null || v === undefined ? '' : v);
				this.editor.startContent = this.editor.getContent({ format: 'raw' });
				this.validate();
				//this.editor.resizeToContent();
			});
		else
			this.editor.onPostRender.add(function(ed, cm) {
				handle.editor.undoManager.clear();
				handle.editor.setContent(v === null || v === undefined ? '' : v);
				handle.editor.startContent = this.editor.getContent({ format: 'raw' });
				handle.validate();
		    });

//			this.editor.onPostRender.add(Ext.Function.bind(function(editor, controlManager) {
//				this.withEd(function() {
//					this.editor.undoManager.clear();
//					this.editor.setContent(v === null || v === undefined ? '' : v);
//					this.editor.startContent = this.editor.getContent({ format: 'raw' });
//					this.validate();
//					//this.editor.resizeToContent();
//				});
//			}, this));
	},

	/** ----------------------------------------------------------
	*/
	isDirty: function() {
		if (this.disabled || !this.rendered) {
			return false;
		}
		return this.editor && this.editor.initialized && this.editor.isDirty();
	},

	/** ----------------------------------------------------------
	*/
	syncValue: function() {
		if (this.rendered && this.editor.initialized)
			this.editor.save();
	},

	/** ----------------------------------------------------------
	*/
	getEditor: function() {
		return this.editor;
	},

	/** ----------------------------------------------------------
	*/
	disable: function() {
		this.withEd(function() {
			var bodyEl = this.editor.getBody();
			bodyEl = Ext.get(bodyEl);

			if (bodyEl.hasCls('mceContentBody')) {
				bodyEl.removeCls('mceContentBody');
				bodyEl.addCls('mceNonEditable');
			}
		});
	},

	/** ----------------------------------------------------------
	*/
	enable: function() {
		this.withEd(function() {
			var bodyEl = this.editor.getBody();
			bodyEl = Ext.get(bodyEl);

			if (bodyEl.hasCls('mceNonEditable')) {
				bodyEl.removeCls('mceNonEditable');
				bodyEl.addCls('mceContentBody');
			}
		});
	},

	/** ----------------------------------------------------------
	*/
	onResize: function(aw, ah) {
		this.callParent(arguments);
		if( Ext.typeOf( aw ) != "number" ){
			aw = this.getWidth();
		}
		if( Ext.typeOf(ah) != "number" ){
			ah = this.getHeight();
		}
		
		debugger;
		if (aw == 0 || ah == 0)
			return;

		if( this.rendered && this.isVisible() ) {
			this.withEd(function() { this._setEditorSize( aw, ah ); });
		}
	},
	
	/** ----------------------------------------------------------
		Sets control size to the given width and height
	*/
	_setEditorSize: function( width, height ) {
	
		// We currently support only advanced theme resize
		if( !this.editor.theme.AdvancedTheme ) return;
	
		// Minimal width and height for advanced theme
		if( width < 100 ) width = 100;
		if( height < 129 ) height = 129;
		
		// Set toolbar div width
		var edTable = Ext.get(this.editor.id + "_tbl"), 
			edIframe = Ext.get(this.editor.id + "_ifr"),
			edToolbar = Ext.get(this.editor.id + "_xtbar");
		
		var toolbarWidth = width;
		if( edTable ) 
			toolbarWidth = width - edTable.getFrameWidth( "lr" );		
		
		var toolbarHeight = 0;
		if( edToolbar ) {
			toolbarHeight = edToolbar.getHeight();
			var toolbarTd = edToolbar.findParent( "td", 5, true );
			toolbarHeight += toolbarTd.getFrameWidth( "tb" );
			edToolbar.setWidth( toolbarWidth );
		}
		
		var edStatusbarTd = edTable.child( ".mceStatusbar" );
		var statusbarHeight = 0;
		if( edStatusbarTd ) {
			statusbarHeight += edStatusbarTd.getHeight();
		}
		
		var iframeHeight = height - toolbarHeight - statusbarHeight;
		var iframeTd = edIframe.findParent( "td", 5, true );
		if( iframeTd )
			iframeHeight -= iframeTd.getFrameWidth( "tb" );
			
		// Resize iframe and container
		edTable.setSize( width, height );
		edIframe.setSize( toolbarWidth, iframeHeight );
	},

	/** ----------------------------------------------------------
	*/
	focus: function(selectText, delay) {
		if (delay) {
			Ext.Function.defer(this.focus, typeof delay == 'number' ? delay : 10, this, [selectText, false]);
			return;
		}

		this.withEd(function() {
			this.editor.focus();
			/*if (selectText === true) {
			// TODO: Select editor's content
			}*/
		});

		return this;
	},

	/** ----------------------------------------------------------
	*/
	processValue : function( value ){
		return Ext.util.Format.stripTags( value );
	},
	
	/** ----------------------------------------------------------
	*/
	validateValue: function( value ) {
		if(Ext.isFunction(this.validator)){
			var msg = this.validator(value);
			if(msg !== true){
				this.markInvalid(msg);
				return false;
			}
		}
		if(value.length < 1 || value === this.emptyText){ // if it's blank
			 if(this.allowBlank){
				 this.clearInvalid();
				 return true;
			 }else{
				 this.markInvalid(this.blankText);
				 return false;
			 }
		}
		if(value.length < this.minLength){
			this.markInvalid(Ext.String.format(this.minLengthText, this.minLength));
			return false;
		}
		if(value.length > this.maxLength){
			this.markInvalid(Ext.String.format(this.maxLengthText, this.maxLength));
			return false;
		}	
		if(this.vtype){
			var vt = Ext.form.field.VTypes;
			if(!vt[this.vtype](value, this)){
				this.markInvalid(this.vtypeText || vt[this.vtype +'Text']);
				return false;
			}
		}
		if(this.regex && !this.regex.test(value)){
			this.markInvalid(this.regexText);
			return false;
		}
		return true;
	},

	/** ----------------------------------------------------------
	If ed (local editor instance) is already initilized, calls
	specified function directly. Otherwise - adds it to ed.onInit event.
	*/
	withEd: function(func) {

		// If editor is not created yet, reschedule this call.
		if (!this.editor) this.on(
			"editorcreated",
			function() { this.withEd(func); },
			this);

		// Else if editor is created and initialized
		else if (this.editor.initialized) func.call(this);

		// Else if editor is created but not initialized yet.
		else this.editor.onInit.add(Ext.Function.bind(function() { Ext.Function.defer(func, 10, this); }, this));
	},
   /**
    * @param component
    * @param adjWidth
    * @param adjHeight
    */
   onResize : function(component, adjWidth, adjHeight){
	   this.callParent(arguments);
       var width;
       var height;
       var bodyWidth = component.getEl().getWidth();
       var bodyHeight = component.getEl().getHeight();
       if (component.iframeEl){
           width = bodyWidth - component.iframeEl.getBorderWidth('lr') - 2;
           height = bodyHeight - component.iframeEl.getBorderWidth('lr') - 125;
           component.iframeEl.setWidth(width);
           component.iframeEl.setHeight(height);
       }
       if (component.tableEl){
           width = bodyWidth - component.tableEl.getBorderWidth('lr') - 2;
           heigth = bodyHeight - component.tableEl.getBorderWidth('lr') - 125;
           component.tableEl.setWidth(width);
           component.tableEl.setHeight(heigth);
       }
      
   },

   afterRender: function(ct, position) {
		this.callParent(arguments);
		
		this.tinyMCESettings.height = this.height - 11;
		 
		// Fix size if it was specified in config
		if (Ext.typeOf(this.width) == "number") {
			this.tinyMCESettings.width = this.width;
		}
		if (Ext.typeOf(this.height) == "number") {
			this.tinyMCESettings.height = this.height;
		}
		 
		//this.el.dom.style.border = '0 none';
		this.el.dom.setAttribute('tabIndex', -1);
		this.el.addClass('x-hidden');
		
		// Wrap textarea into DIV
		this.textareaEl = this.el;
		var wrapElStyle = { overflow: "hidden" };
		if( Ext.isIE ) { // fix IE 1px bogus margin
			wrapElStyle["margin-top"] = "-1px";
			wrapElStyle["margin-bottom"] = "-1px";
		}
		this.wrapEl = this.el.wrap({ style: wrapElStyle });
		this.actionMode = "wrapEl"; // Set action element to the new wrapper
		this.positionEl = this.wrapEl;
		
		//this.el.dom.style.border = '0 none';
		//this.el.dom.setAttribute('tabIndex', -1);
		//this.el.addCls('x-hidden');
		
		var id = this.getId();

		// Create TinyMCE editor.
		this.editor = new tinymce.Editor(id, this.tinyMCESettings);
		
		// Validate value onKeyPress
		var validateContentTask = Ext.Function.createBuffered(this.validate, 250, this);
		this.editor.onKeyPress.add(validateContentTask);
		
		this.editor.onPostRender.add(Ext.Function.bind(function(editor, controlManager) {
			// Change window manager
			editor.windowManager = Ext.create("EC.common.tinymce.WindowManager", {
				editor: this.editor
			});
			this.tableEl = Ext.get(this.editor.id + "_tbl");
            this.iframeEl = Ext.get(this.editor.id + "_ifr");
		}, this));

		// Wire "change" event
		this.editor.onChange.add(Ext.Function.bind(function(ed, l) {
			this.fireEvent("change", ed, l);
		}, this));

		// Render the editor
		this.editor.render();
		tinyMCE.add(this.editor);
		
		this.setValue(this.value);
		this.on('resize', this.onResize, this);
	}
});